package com.haidung.photojourney.models;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.google.android.gms.maps.GoogleMap;
import com.haidung.photojourney.events.EventDispatcher;
import com.haidung.photojourney.events.SimpleEvent;
import com.haidung.photojourney.vos.JourneyMarker;
import com.twotoasters.clusterkraf.Clusterkraf;
import com.twotoasters.clusterkraf.InputPoint;
import com.twotoasters.clusterkraf.Options;
import com.twotoasters.clusterkraf.Options.ClusterClickBehavior;

public class GoogleMapModel extends EventDispatcher {
    public static class MapEvent extends SimpleEvent {
        public static final String ADD_MARKER = "ADD_MARKER";
        public static final String INIT_MAP = "INIT_MAP";

        public MapEvent(String type) {
            super(type);
        }

        public MapEvent(String type, Object value) {
            super(type, value);
        }

    }

    private static GoogleMapModel instance;
    private List<JourneyMarker> markers = new ArrayList<JourneyMarker>();
    private Options options;
    private Clusterkraf clusterkraf;

    private GoogleMapModel() {
        super();
        options = new Options();
        options.setClusterClickBehavior(ClusterClickBehavior.ZOOM_TO_BOUNDS);
    }

    public synchronized static GoogleMapModel getInstance() {
        if (instance == null)
            instance = new GoogleMapModel();
        return instance;
    }

    private void notifyChange(String type, Object value) {
        if (value == null) {
            dispatchEvent(new MapEvent(type));
            return;
        }
        dispatchEvent(new MapEvent(type, value));
    }

    public List<JourneyMarker> getMarkers() {
        return Collections.unmodifiableList(this.markers);
    }

    public void addMarker(JourneyMarker marker) {
        this.markers.add(marker);
        this.clusterkraf.add(new InputPoint(marker.getMarker().getPosition()));
        notifyChange(MapEvent.ADD_MARKER, marker);
    }

    public void notifyInitMap() {
        notifyChange(MapEvent.INIT_MAP, null);
    }

    public Options getOptions() {
        return options;
    }

    public void setOptions(Options options) {
        this.options = options;
    }

    public Clusterkraf getClusterkraf() {
        return clusterkraf;
    }

    public void setClusterkraf(GoogleMap map) {
        this.clusterkraf = new Clusterkraf(map, options, new ArrayList<InputPoint>());
    }
}
